package base.shiro.demo.autho2;

import base.shiro.demo.user.PermissionsEntity;
import base.shiro.demo.user.RoleEntity;
import base.shiro.demo.user.UserEntity;
import base.shiro.demo.user.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.stream.Collectors;

public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    public boolean supports(AuthenticationToken token) {
//        return token instanceof CustomToken;
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 权限配置
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        UserEntity user = (UserEntity) principalCollection.getPrimaryPrincipal();
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (RoleEntity role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            simpleAuthorizationInfo.addStringPermissions(role.getPermissionsList().stream().map(PermissionsEntity::getPermissionsName).collect(Collectors.toList()));
        }
        return simpleAuthorizationInfo;
    }

    /**
     * 认证配置
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
            throw new IncorrectCredentialsException("请登录!");
        }
        // 获取用户信息
        String token = (String)authenticationToken.getPrincipal();
        // TODO: 2021/11/12 根据token获取
        UserEntity user = userService.getUserByName(token);
        if (user == null) {
            //这里返回后会报出对应异常
            throw new IncorrectCredentialsException("token失效，请重新登录!");
        } else {
            if(user.getStatus() == 0){
                throw new LockedAccountException("账号已被锁定");
            }
            //这里验证authenticationToken和simpleAuthenticationInfo的信息，param1=主体，param2=证书，param3=获得主体和证书的范围
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
            return simpleAuthenticationInfo;
        }
    }

}
